#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#include "eXosip2/eXosip2.h"  
#include "eXosip2/eX_call.h"
#include "eXosip2/eX_setup.h"
#include "osipparser2/osip_parser.h" 
#include "osipparser2/osip_message.h"
#include "osipparser2/osip_body.h"

#include "od_trace.h"
#include "od_task.h"
#include "od_os.h"
#include "od_engine.h"
#include "od_sip_comn.h"
#include "od_sip_other_event.h"
#include "od_sip_message.h"
#include "od_sip_event_distributor.h"


#define SIP_HANDLE_EVENT_TSK_STACK_SIZE  (4*1024 * 1024)   /*线程栈资源大小*/


typedef struct
{
    TASK_COMMON_MEMBERS

    pipeline_handle g_event_pipe;
    od_sip_ctx *ctx;
    eXosip_event_t *event;
    od_sip_event_queue evt_que;
}od_sip_other_evt_obj;


static int sip_other_evt_handle_event(od_sip_other_evt_obj *obj)
{
    int retval = OD_OK;
    
    switch (obj->event->type)  
    {  
        case EXOSIP_MESSAGE_NEW:
            RPTDBG("EXOSIP_MESSAGE_NEW");
            retval = od_sip_msg_call_message_new(obj->ctx, obj->event, -1); 
            break;

        case EXOSIP_MESSAGE_ANSWERED:          
            RPTDBG("EXOSIP_MESSAGE_ANSWERED");
            break;

        case EXOSIP_MESSAGE_REQUESTFAILURE:            
            RPTDBG("EXOSIP_MESSAGE_REQUESTFAILURE");
            break;

        default:
            RPTWRN("un-process:[%s]\n", obj->event->textinfo);  
            break;
    }

    eXosip_event_free(obj->event);
    return retval;
}


static int sip_other_evt_start_stop(od_sip_other_evt_obj *obj)
{
    static pj_thread_desc thread_desc;
    pj_thread_t *thread;
    pipeline_attrs fAttrs = pipeline_attrs_default;

    obj->ctx = od_sip_lib_start();
    OD_SIP_ASSERT_RETURN(obj->ctx, OD_EFAULT);

    if (!pj_thread_is_registered()) {
        pj_bzero(thread_desc, sizeof(pj_thread_desc));
        pj_thread_register(obj->task_name, thread_desc, &thread);
    }

    /*create event pipe*/
    obj->g_event_pipe = pipeline_create(&fAttrs);
    if (!obj->g_event_pipe) {
        RPTERR("create event pipe error!!");
        return OD_ERROR;
    }

    /*register to event distributor pthread to get event!!*/
    obj->evt_que.tsk_name = obj->task_name;
    obj->evt_que.queue_type = OD_SIP_EVT_QUEUE_TYPE_OTHER;
    obj->evt_que.g_event_pipe = obj->g_event_pipe;
    if (od_sip_evt_distrb_add(&obj->evt_que) != OD_OK) {
        RPTERR("add handle_event que pipe error!");
        return OD_ERROR;
    }

    return OD_OK;
}

static void sip_other_evt_start_stop_delete(od_sip_other_evt_obj *obj)
{
    od_sip_lib_stop();
    od_sip_evt_distrb_remove(&obj->evt_que);
    pipeline_delete(obj->g_event_pipe);
}

static int sip_other_evt_process(od_sip_other_evt_obj *obj)
{   
    if (od_sip_get_event(obj->g_event_pipe, &obj->event) < 0) {
        od_msleep(50);
        return OD_OK;
    }

    return sip_other_evt_handle_event(obj);
}


od_sip_other_event_handle od_sip_other_event_create(od_sip_other_event_static_params *static_params,
                                                        od_sip_other_event_dynamic_params *dynamic_params)
{
    od_sip_other_evt_obj *obj = NULL;

    OD_SIP_ASSERT_RETURN(static_params, NULL);

    obj = od_task_create((char *)static_params->task_name, sizeof(od_sip_other_evt_obj));
    OD_SIP_ASSERT_RETURN(obj, NULL);

    obj->tab = NULL;
    obj->params_nums = 0;
    obj->params = NULL;
    obj->stack_size = SIP_HANDLE_EVENT_TSK_STACK_SIZE;
    obj->pf_start_stop  = (void *)sip_other_evt_start_stop;
    obj->pf_malloc_free = NULL;
    obj->pf_rt_set = NULL;
    obj->pf_process     = (void *)sip_other_evt_process;
    obj->pf_malloc_free_delete = NULL;
    obj->pf_start_stop_delete = (void *)sip_other_evt_start_stop_delete;

    RPTDBG("create success");
    return (od_sip_other_event_handle)obj;
}


/*_*/


